<template>
  <div
    v-if="show"
    class="shadow-lg mx-auto w-[90%] text-sm pointer-events-auto bg-clip-padding rounded-lg block mb-3"
    :class="[colors.bg, colors.text]"
  >
    <div
      class="flex justify-between items-center py-2 px-3 bg-clip-padding border-b rounded-t-lg"
      :class="[colors.border]"
    >
      <p class="flex items-center">
        <svg
          xmlns="http://www.w3.org/2000/svg"
          class="w-4 h-4"
          :class="[colors.icon]"
          viewBox="0 0 20 20"
          fill="currentColor"
        >
          <use :xlink:href="`#z-icons-${type}`" />
        </svg>
        <span class="font-bold px-2">{{ title }}</span>
      </p>
      <div class="flex items-center">
        <p v-if="tip" class="opacity-80 text-xs px-2">{{ tip }}</p>
        <svg
          xmlns="http://www.w3.org/2000/svg"
          class="w-4 h-4 stroke-cap-round stroke-join-round stroke-2 cursor-pointer"
          stroke="currentColor"
          viewBox="0 0 24 24"
          @click="close"
        >
          <path d="M6 18L18 6M6 6l12 12" />
        </svg>
      </div>
    </div>
    <slot>
      <div class="p-3 rounded-b-lg break-words">
        {{ message }}
      </div>
    </slot>
  </div>
</template>
<script lang="ts">
import { defineComponent, PropType, computed, ref, watch } from "vue";

export type NoticeType = "default" | "success" | "info" | "warning" | "error";
export interface Color {
  bg: string;
  border: string;
  icon: string;
  text: string;
}
const Colors: Record<NoticeType, Color> = {
  default: {
    bg: "bg-gray-100",
    border: "border-gray-300",
    icon: "text-bg-blue-600",
    text: "text-gray-500",
  },
  success: {
    bg: "bg-green-500",
    border: "border-green-400",
    icon: "text-white",
    text: "text-white",
  },
  info: {
    bg: "bg-blue-600",
    border: "border-blue-500",
    icon: "text-white",
    text: "text-white",
  },
  warning: {
    bg: "bg-yellow-500",
    border: "border-yellow-400",
    icon: "text-white",
    text: "text-white",
  },
  error: {
    bg: "bg-red-600",
    border: "border-red-500",
    icon: "text-white",
    text: "text-white",
  },
};
export default defineComponent({
  name: "ZNotice",
  props: {
    modelValue: {
      type: Boolean,
      default: true,
    },
    type: {
      type: String as PropType<NoticeType>,
      default: "error",
    },
    name: String,
    title: String,
    message: String,
    tip: String,
    duration: Number,
  },
  emits: ["close", "update:model-value"],
  setup(props, { emit }) {
    const colors = computed(() => Colors[props.type]);

    const show = ref(props.modelValue),
      close = () => {
        if (!show.value) return;
        // close
        show.value = false;
        emit("update:model-value", false);
        // close event
        emit("close", props.name);
      };
    // 按时间自动关闭
    if (show.value && props.duration) setTimeout(close, props.duration);
    watch(
      () => props.modelValue,
      (val) => {
        show.value = val;
        if (show.value && props.duration) setTimeout(close, props.duration);
      }
    );
    return {
      colors,
      show,
      close,
    };
  },
});
</script>
